home *** CD-ROM | disk | FTP | other *** search
/ World of Sound / World of Sound.iso / utils / modplayers / tracker / automaton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  5.4 KB  |  228 lines

  1. /* automaton.c */
  2.  
  3. /* $Id: automaton.c,v 3.15 1993/11/17 15:31:16 espie Exp espie $
  4.  * $Log: automaton.c,v $
  5.  * Revision 3.15  1993/11/17  15:31:16  espie
  6.  * *** empty log message ***
  7.  *
  8.  * Revision 3.13  1993/07/18  10:39:44  espie
  9.  * Fixed up repeat code, should work better now.
  10.  *
  11.  * Revision 3.12  1993/07/17  22:23:41  espie
  12.  * Fixed bug with bad loops.
  13.  *
  14.  * Revision 3.9  1993/05/09  14:06:03  espie
  15.  * Modified the way set_speed works.
  16.  *
  17.  * Revision 3.8  1993/01/16  17:00:27  espie
  18.  * Corrected stupid bug (run_in_fg)
  19.  *
  20.  * Revision 3.7  1993/01/15  14:00:28  espie
  21.  * Added bg/fg test.
  22.  *
  23.  * Revision 3.6  1992/11/27  10:29:00  espie
  24.  * General cleanup
  25.  *
  26.  * Revision 3.5  1992/11/24  10:51:19  espie
  27.  * un#ifdef'ed showseq code.
  28.  *
  29.  * Revision 3.3  1992/11/22  17:20:01  espie
  30.  * Simplified delay_pattern.
  31.  *
  32.  * Revision 3.2  1992/11/20  14:53:32  espie
  33.  * Added finetune.
  34.  *
  35.  * Revision 3.1  1992/11/19  20:44:47  espie
  36.  * Protracker commands.
  37.  *
  38.  * Revision 3.0  1992/11/18  16:08:05  espie
  39.  * New release.
  40.  *
  41.  * Revision 2.16  1992/11/17  17:15:37  espie
  42.  * New output for new interface
  43.  * Modified repeat logic: now works irregardless of repeat points.
  44.  * start
  45.  *
  46.  * Revision 2.8  1992/07/14  14:23:41  espie
  47.  * Changed fine speed command and comments.
  48.  * Added two level of fault tolerancy.
  49.  */
  50.      
  51.  
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55.      
  56. #include "defs.h"
  57. #include "extern.h"
  58. #include "song.h"
  59. #include "channel.h"
  60.      
  61. LOCAL char *id = "$Id: automaton.c,v 3.15 1993/11/17 15:31:16 espie Exp espie $";
  62.      
  63.  
  64. LOCAL void clear_repeats(a, from, upto)
  65. struct automaton *a;
  66. int from, upto;
  67.     {
  68.     int i;
  69.  
  70.     for (i = from; i <= upto; i++)
  71.         a->gonethrough[i] = FALSE;
  72.     }
  73.  
  74. LOCAL void reset_repeats(a)
  75. struct automaton *a;
  76.     {
  77.     clear_repeats(a, 0, a->info->length);
  78.     a->gonethrough[a->info->length] = TRUE;
  79.     }
  80.  
  81. /* updates the pattern to play in the automaton.
  82.  * Checks that the pattern actually exists.
  83.  * Checks for repetitions as well.
  84.  */
  85. LOCAL void set_pattern(a)
  86. struct automaton *a;
  87.     {
  88.     int p;
  89.  
  90.  
  91.     if (a->pattern_num >= a->info->length)
  92.         {
  93.         error = UNRECOVERABLE;
  94.         return;
  95.         }
  96.  
  97.     if (a->gonethrough[a->pattern_num])
  98.         {
  99.         error = ENDED;
  100.         reset_repeats(a);
  101.         }
  102.     else
  103.         a->gonethrough[a->pattern_num] = TRUE;
  104.  
  105.     if (run_in_fg())
  106.         {
  107.         if (show)
  108.             printf("\n%3d/%3d\n", a->pattern_num, a->info->length);
  109.         else
  110.             printf("%3d/%3d\b\b\b\b\b\b\b", a->pattern_num, a->info->length);
  111.         fflush(stdout); 
  112.         }
  113.         /* there is a level of indirection in the format,
  114.          * i.e., patterns can be repeated.
  115.          */
  116.     p = a->info->patnumber[a->pattern_num];
  117.     if (p >= a->info->maxpat)
  118.         {
  119.         error = UNRECOVERABLE;
  120.         return;
  121.         }
  122.     a->pattern = a->info->pblocks + p;
  123.     }
  124.  
  125. /* initialize all the fields of the automaton necessary
  126.  * to play a given song.
  127.  */
  128. void init_automaton(a, song, start)
  129. struct automaton *a;
  130. struct song *song;
  131. int start;
  132.     {
  133.     a->info = &song->info;
  134.     a->pattern_num = start;     /* first pattern */
  135.  
  136.     a->loop_note_num = 0;
  137.     a->loop_counter = 0;
  138.  
  139.     reset_repeats(a);
  140.  
  141.     a->note_num = 0;        /* first note in pattern */
  142.     a->counter = 0;         /* counter for the effect tempo */
  143.     a->speed = NORMAL_SPEED;/* this is the default effect tempo */
  144.     a->finespeed = NORMAL_FINESPEED;    
  145.                             /* this is the fine speed (100%=NORMAL_FINESPEED) */
  146.     a->do_stuff = DO_NOTHING;   
  147.                             /* some effects affect the automaton,
  148.                              * we keep them here.
  149.                              */
  150.  
  151.     error = NONE;           /* Maybe we should not reset errors at
  152.                              * this point.
  153.                              */
  154.     set_pattern(a);
  155.     }
  156.  
  157. /* Gets to the next pattern, and displays stuff */
  158. LOCAL void advance_pattern(a)
  159. struct automaton *a;
  160.     {
  161.     if (run_in_fg() && show)
  162.         printf("\n\n");
  163.     if (++a->pattern_num >= a->info->length)
  164.         a->pattern_num = 0;
  165.     set_pattern(a);
  166.     a->note_num = 0;
  167.     }
  168.  
  169.         
  170.  
  171. /* process all the stuff which we need to advance in the song,
  172.  * including set_speed, set_skip, set_fastskip, and set_loop.
  173.  */
  174. void next_tick(a)
  175. struct automaton *a;
  176.     {
  177.             /* there are three classes of speed changes:
  178.              * 0 does nothing. (should stop)
  179.              * <32 is the effect speed (resets the fine speed).
  180.              * >=32 changes the finespeed, default 125
  181.              */
  182.     if ((a->do_stuff & SET_SPEED) && (a->do_stuff & SET_FINESPEED))
  183.         {
  184.         a->speed = a->new_speed;
  185.         a->finespeed = a->new_finespeed;
  186.         }
  187.     else if (a->do_stuff & SET_FINESPEED)
  188.         {
  189.         a->finespeed = a->new_finespeed;
  190.         }
  191.     else if (a->do_stuff & SET_SPEED)
  192.         {
  193.         a->speed = a->new_speed;
  194.         /*
  195.         a->finespeed = NORMAL_FINESPEED;
  196.         */
  197.         }
  198.  
  199.     if (++a->counter >= a->speed)
  200.         {
  201.         a->counter = 0;
  202.         if (run_in_fg() && show)
  203.             printf("\n");
  204.             /* loop: may change note in pattern right away */
  205.         if ((a->do_stuff & JUMP_PATTERN) && --a->loop_counter > 0)
  206.             a->note_num = a->loop_note_num;
  207.         else if (a->do_stuff & SET_FASTSKIP)
  208.             {
  209.             a->pattern_num = a->new_pattern;
  210.             set_pattern(a);
  211.             a->note_num = 0;
  212.             }
  213.         else if (a->do_stuff & SET_SKIP)
  214.             {
  215.             advance_pattern(a);
  216.             a->note_num = a->new_note;
  217.             }
  218.         else
  219.             {
  220.             if (++a->note_num >= BLOCK_LENGTH)
  221.                 advance_pattern(a);
  222.             }
  223.         a->do_stuff = DO_NOTHING;
  224.         }
  225.     }
  226.  
  227.  
  228.